﻿using System;
using System.Drawing;
using System.Drawing.Imaging;


	/// <summary>
	/// Contains methods for image manipulation
	/// </summary>
	public class ImageFilter
	{
		/// <summary>
		/// Initialize a new instance of the ImageFilter class
		/// </summary>
		public ImageFilter()
		{
		}

		
		/// <summary>
		/// Crops an image
		/// </summary>
		/// <param name="bm">Image to crop</param>
		/// <param name="rect">Rectangle representing </param>
		/// <returns>Bitmap containing the cropped image</returns>
		public static Bitmap Crop (Bitmap bm, System.Drawing.Rectangle rect)
		{
			return Crop (bm, rect.X, rect.Y, rect.Width, rect.Height);
		}
		
		/// <summary>
		/// Crops an image
		/// </summary>
		/// <param name="bm">Image to crop</param>
		/// <param name="x">X-coordinate of the start position in pixels from the upper-left corner</param>
		/// <param name="y">Y-coordinate of the start position in pixels from the upper-left corner</param>
		/// <param name="width">Width of the area to crop</param>
		/// <param name="height">Height of the area to crop</param>
		/// <returns>Bitmap containing the cropped image</returns>
		public static Bitmap Crop (Bitmap bm, int x, int y, int width, int height)
		{
			Bitmap cropped = new Bitmap(width,height);
			Graphics g = Graphics.FromImage(cropped);
			g.DrawImage(bm, new Rectangle(0,0,cropped.Width,cropped.Height), x, y, cropped.Width, cropped.Height, GraphicsUnit.Pixel);
			g.Dispose();
			return cropped;
		}

		/// <summary>
		/// Resize an image 
		/// </summary>
		/// <param name="bm">Bitmap to resize</param>
		/// <param name="size">New size of the image</param>
		/// <returns>Bitmap containing the resized image</returns>
		public static Bitmap ImageResize(Bitmap bm, Size size)
		{
			Bitmap bitmap = new Bitmap(size.Width, size.Height, bm.PixelFormat);
			Graphics g = Graphics.FromImage(bitmap);
			g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
			g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
			g.DrawImage(bm, 0, 0, bitmap.Width, bitmap.Height);
			
			g.Dispose();
			return bitmap;
		}

		/// <summary>
		/// Convert colour to grayscale
		/// </summary>
		/// <param name="original">Bitmap to convert</param>
		/// <returns>Bitmap containing the converted image</returns>
		public static Bitmap Grayscale (Bitmap original)
		{
			Bitmap bm = new Bitmap(original.Width,original.Height);
			Graphics g = Graphics.FromImage(bm);

			ColorMatrix cm = new ColorMatrix(new float[][] {   
				new float[]{0.3f,0.3f,0.3f,0,0},
				new float[]{0.59f,0.59f,0.59f,0,0},
				new float[]{0.11f,0.11f,0.11f,0,0},
				new float[]{0,0,0,1,0,0},
				new float[]{0,0,0,0,1,0},
				new float[]{0,0,0,0,0,1}});
			
			ImageAttributes ia = new ImageAttributes();
			ia.SetColorMatrix(cm);
			g.DrawImage(original,new Rectangle(0,0,original.Width,original.Height),0,0,original.Width,original.Height,GraphicsUnit.Pixel,ia);
			g.Dispose();
			return bm;
		}

		/// <summary>
		/// Change the colour of an image
		/// </summary>
		/// <param name="original">Bitmap to change</param>
		/// <param name="red">Red value</param>
		/// <param name="green">Green value</param>
		/// <param name="blue">Blue value</param>
		/// <returns>Changed bitmap</returns>
		public static Bitmap Colour (Bitmap original, int red, int green, int blue)
		{
			Bitmap bm = new Bitmap(original.Width,original.Height);
			Graphics g = Graphics.FromImage(bm);

			float nRed, nGreen, nBlue;
			nRed = red / 255.0f;
			nGreen = green / 255.0f;
			nBlue = blue / 255.0f;

			ColorMatrix cm = new ColorMatrix(new float[][] {   
				new float[]{1,0,0,0,0},
				new float[]{0,1,0,0,0},
				new float[]{0,0,1,0,0},
				new float[]{0,0,0,1,0},
				new float[]{nRed,nGreen,nBlue,1,1,}});

			ImageAttributes ia = new ImageAttributes();
			ia.SetColorMatrix(cm);
			g.DrawImage(original,new Rectangle(0,0,original.Width,original.Height),0,0,original.Width,original.Height,GraphicsUnit.Pixel,ia);
			g.Dispose();
			return bm;
		}

		/// <summary>
		/// Change the brightness of an image.
		/// </summary>
		/// <param name="original">Bitmap to change.</param>
		/// <param name="brightness">Brightness factor</param>
		/// <returns>Changed bitmap.</returns>
		public static Bitmap Brightness (Bitmap original, int brightness) 
		{
			Bitmap bm = new Bitmap(original.Width,original.Height);
			Graphics g = Graphics.FromImage(bm);

			float bf = brightness / 100.0f;

			ColorMatrix cm = new ColorMatrix(new float[][] {  
				new float[]{1,0,0,0,0},
				new float[]{0,1,0,0,0},
				new float[]{0,0,1,0,0},
				new float[]{0,0,0,1,0},
				new float[]{bf,bf,bf,1,1,}});

			ImageAttributes ia = new ImageAttributes();
			ia.SetColorMatrix(cm);
			g.DrawImage(original,new Rectangle(0,0,original.Width,original.Height),0,0,original.Width,original.Height,GraphicsUnit.Pixel,ia);
			g.Dispose();
			return bm;
		}

		/// <summary>
		/// Change the contrast of an image.
		/// </summary>
		/// <param name="original">Image to change.</param>
		/// <param name="contrast">Contrast factor.</param>
		/// <returns>Changed image.</returns>
		public static Bitmap Contrast (Bitmap original, int contrast)
		{
			Bitmap bm = new Bitmap(original.Width,original.Height);
			Graphics g = Graphics.FromImage(bm);

			float cf = contrast / 100.0f;

			ColorMatrix cm = new ColorMatrix(new float[][] {  
				new float[] {cf, 0, 0, 0, 0},
				new float[] {0, cf, 0, 0, 0},
				new float[] {0, 0, cf, 0, 0},
				new float[] {0, 0, 0, 1, 0},
				new float[] {0.001f, 0.001f, 0.001f, 0, 1}});

			ImageAttributes ia = new ImageAttributes();
			ia.SetColorMatrix(cm);
			g.DrawImage(original,new Rectangle(0,0,original.Width,original.Height),0,0,original.Width,original.Height,GraphicsUnit.Pixel,ia);
			g.Dispose();
			return bm;
		}

		public static Bitmap Smooth(Bitmap original, int nWeight /* default to 1 */)
		{
			Bitmap bm = new Bitmap(original.Width,original.Height);
			return bm;
		}

		public static Bitmap Sharpen(Bitmap original, int nWeight /* default to 11*/ )
		{
			Bitmap bm = new Bitmap(original.Width,original.Height);
			return bm;
		}


        public static bool IsFileAnImage(System.IO.Stream fileStream)
        {
            bool RetVal = true;
            try
            {
                System.Drawing.Image img = System.Drawing.Image.FromStream(fileStream);
                img.Dispose();
            }
            catch
            {
                RetVal = false;
            }
            return RetVal;
        }
	}
